package com.xiangban.yanglaodajie_platform.service;

import com.alibaba.fastjson.JSONArray;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.xiangban.yanglaodajie_platform.dao.*;
import com.xiangban.yanglaodajie_platform.entity.*;
import com.xiangban.yanglaodajie_platform.entity.dto.*;
import com.xiangban.yanglaodajie_platform.entity.res.ApiResultCode;
import com.xiangban.yanglaodajie_platform.entity.vo.DateVo;
import com.xiangban.yanglaodajie_platform.exception.BizException;
import com.xiangban.yanglaodajie_platform.utils.CommonUtils;
import com.xiangban.yanglaodajie_platform.utils.DateUtil;
import com.xiangban.yanglaodajie_platform.utils.PageUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

import static com.xiangban.yanglaodajie_platform.utils.CommonUtils.BizEmpty;
import static com.xiangban.yanglaodajie_platform.utils.CommonUtils.getOrderNo;
import static com.xiangban.yanglaodajie_platform.utils.DateUtil.getDistance;
import static com.xiangban.yanglaodajie_platform.utils.DateUtil.getWeekOfDate;

/**
 * @Author Mr. MaYaYun
 * @Data 2021/5/8 17:27
 */
@Service
public class OrdersClassOrActivityService {
    private final int excursionTime = 10;

    @Autowired
    private OrdersClassOrActivityMapper ordersClassOrActivityMapper;
    @Autowired
    private CommonUtils commonUtils;
    @Autowired
    private HttpServletRequest request;
    @Autowired
    private UserMapper userMapper;
    @Autowired
    private ClassOrActivityMapper classOrActivityMapper;
    @Autowired
    private PageUtil pageUtil;
    @Autowired
    private AccumulatePointsMapper accumulatePointsMapper;
    @Autowired
    private RefundMapper refundMapper;
    @Autowired
    private ShopLoginMapper shopLoginMapper;
    @Autowired
    private WalletLogMapper walletLogMapper;
    @Autowired
    private TeacherService teacherService;


    @Transactional
    public Object createOrders(OrdersClassOrActivity ordersClassOrActivity){//参数：商品id和用户id
        ordersClassOrActivity.setUserId(Integer.parseInt(commonUtils.getUserId(request)));
        if (BizEmpty(commonUtils.getUserId(request))) {
            throw new BizException(ApiResultCode.PARAMETER_DEFICIENCY);
        }
        if (BizEmpty(ordersClassOrActivity.getClassOrActivityId())) {
            throw new BizException(ApiResultCode.PARAMETER_DEFICIENCY);
        }
        ClassOrActivity classOrActivity = new ClassOrActivity();
        classOrActivity.setId(ordersClassOrActivity.getClassOrActivityId());
        ClassOrActivity activityPrice = classOrActivityMapper.getActivityPrice(classOrActivity);//查询出这个商品
        if (activityPrice.getNumber()>activityPrice.getInventory()){//报名人数已满
            throw new BizException(ApiResultCode.ACTIVITY_FULL);
        }
        String orderNo = getOrderNo();//生成订单编号
        //查询是否报名课程
        OrdersClassOrActivity orders = ordersClassOrActivityMapper.findOrdersByUserIdAndClassOrActivityId(ordersClassOrActivity);
        //订单不存在未报名
        if (BizEmpty(orders)) {
            //判断是否存在上级课程
            if (activityPrice.getIsParent() == 1){
                Integer classPid = activityPrice.getClassPid();
                OrdersClassOrActivity ordersClassOrActivity1 = new OrdersClassOrActivity();
                ordersClassOrActivity1.setUserId(Integer.parseInt(commonUtils.getUserId(request)));
                ordersClassOrActivity1.setClassOrActivityId(classPid);
                OrdersClassOrActivity orders1 = ordersClassOrActivityMapper.findOrdersByUserIdAndClassOrActivityId(ordersClassOrActivity1);
                if (orders1 == null){
                    classOrActivity.setId(classPid);
                    ClassOrActivity activityPrice1 = classOrActivityMapper.getActivityPrice(classOrActivity);
                    throw new BizException(20030,"您未报名【"+activityPrice1.getClassName()+"】课程");
                }
            }
            //判断是否截止报名
            Date endTime = activityPrice.getEndTime();
            Date date = new Date();
            if (date.getTime()>endTime.getTime()){
                throw new BizException(ApiResultCode.ACTIVITY_PAST);
            }
            //添加到订单查看
            ordersClassOrActivity.setCreateTime(new Date());
            ordersClassOrActivity.setOrdersNumber(orderNo);
            ordersClassOrActivity.setShopId(activityPrice.getShopId());
            ordersClassOrActivity.setStatus(1);
            ordersClassOrActivityMapper.saveOrders(ordersClassOrActivity);
        }else {//订单存在已报名
            throw new BizException(ApiResultCode.ORDERS_EXIST);
        }
        HashMap<String, Object> map = new HashMap<>();
        map.put("ordersNumber",orderNo);
        return map;
    }


    /**
     * 参数：订单编号
     * @param ordersClassOrActivity
     */
    public void cancelOrders(OrdersClassOrActivity ordersClassOrActivity) {
        if (BizEmpty(commonUtils.getUserId(request))){
            throw new BizException(ApiResultCode.PARAMETER_DEFICIENCY);
        }
        if (BizEmpty(ordersClassOrActivity.getOrdersNumber())){
            throw new BizException(ApiResultCode.PARAMETER_DEFICIENCY);
        }
        ordersClassOrActivity.setUserId(Integer.parseInt(commonUtils.getUserId(request)));

        ordersClassOrActivityMapper.updateStatus(ordersClassOrActivity);
    }


    @Transactional
    public void payOrders(OrdersClassOrActivity ordersClassOrActivity) {//参数：订单编号
        ordersClassOrActivity.setUserId(Integer.parseInt(commonUtils.getUserId(request)));
        if (BizEmpty(ordersClassOrActivity.getOrdersNumber())) {
            throw new BizException(ApiResultCode.PARAMETER_DEFICIENCY);
        }

        UserDto userDto = new UserDto();
        userDto.setUserId(ordersClassOrActivity.getUserId());
        UserDto userInfoById = userMapper.getUserInfoById(userDto);//查询出这个用户的积分
        BigDecimal accumulatePoints = userInfoById.getAccumulatePoints();//用户积分

        //查询出要付款订单
        OrdersClassOrActivity ordersClassOrActivity2 = ordersClassOrActivityMapper.selectOrderByOrdersNumber(ordersClassOrActivity);

        Integer classOrActivityId = ordersClassOrActivity2.getClassOrActivityId();
        ordersClassOrActivity.setClassOrActivityId(classOrActivityId);
        List<OrdersClassOrActivity> order = ordersClassOrActivityMapper.seletctOrderByUserIdAndClassOrActivityId(ordersClassOrActivity);
        for (OrdersClassOrActivity classOrActivity : order) {
            if (classOrActivity.getStatus() == 0){
                throw new BizException(ApiResultCode.EXIST_ORDERS);
            }
        }



        ClassOrActivity classOrActivity = new ClassOrActivity();
        classOrActivity.setId(ordersClassOrActivity2.getClassOrActivityId());
        ClassOrActivity activityPrice = classOrActivityMapper.getActivityPrice(classOrActivity);//查询出这个商品
        BigDecimal price = activityPrice.getPrice();//活动价格

        if (accumulatePoints.compareTo(price) < 0) {//积分不足
            throw new BizException(ApiResultCode.PRICE_DEFICIENCY);
        }

        HashMap<String, Object> map = new HashMap<>();
        map.put("newPoints", accumulatePoints.subtract(price));//结算后的积分
        map.put("userId", ordersClassOrActivity.getUserId());
        userMapper.updAccumulatePoints(map);//更改账户积分
        //商家帐户积分增加 TODO

        classOrActivityMapper.updateNumber(activityPrice);//更改报名人数

        AccumulatePoints accumulatePoints1 = new AccumulatePoints();
        accumulatePoints1.setUserId(ordersClassOrActivity.getUserId());
        accumulatePoints1.setPayState(0);//支付状态1：未支付，0：已支付
        accumulatePoints1.setType(2);//流水类型(1:收入，2:支出)
        accumulatePoints1.setAccumulatePoints(price);
        accumulatePoints1.setOrderNumber(ordersClassOrActivity.getOrdersNumber());
        accumulatePoints1.setDescribe("活动消费");//描述
        accumulatePoints1.setRecodeType(3);//记录类型 0 充值 1 打卡 2 商品消费 3 活动消费
        accumulatePointsMapper.saveAP(accumulatePoints1);//添加积分记录

        //更改订单状态
        ordersClassOrActivityMapper.updateOrderStatus(ordersClassOrActivity);

    }

    /**
     * 参数：用户id
     * @param ordersClassOrActivity
     * @return 课程订单列表
     */
    public PageInfo<OrdersClassOrActivityDto> classOrActivityOrdersList(OrdersClassOrActivity ordersClassOrActivity) {
        PageHelper.startPage(pageUtil.getPage().getPageNum(), pageUtil.getPage().getPageSize());
        ordersClassOrActivity.setUserId(Integer.parseInt(commonUtils.getUserId(request)));
        if (BizEmpty(ordersClassOrActivity.getUserId())) {
            throw new BizException(ApiResultCode.PARAMETER_DEFICIENCY);
        }
        List<OrdersClassOrActivityDto> ordersByUserId = ordersClassOrActivityMapper.selectOrdersList(ordersClassOrActivity);
        if (ordersByUserId != null){
            return new PageInfo<>(ordersByUserId);
        }else {
            return new PageInfo<>();
        }

    }

    /**
     * 参数：用户id、订单编号
     * @param ordersClassOrActivity
     * @return 课程订单详情
     */
    public Object classOrActivityOrdersInfo(OrdersClassOrActivity ordersClassOrActivity){
        if (BizEmpty(commonUtils.getUserId(request))){
            throw new BizException(ApiResultCode.PARAMETER_DEFICIENCY);
        }
        if (BizEmpty(ordersClassOrActivity.getOrdersNumber())){
            throw new BizException(ApiResultCode.PARAMETER_DEFICIENCY);
        }
        ordersClassOrActivity.setUserId(Integer.parseInt(commonUtils.getUserId(request)));
        OrdersClassOrActivityDto ordersClassOrActivityDto = ordersClassOrActivityMapper.selectOrdersInfo(ordersClassOrActivity);
        return ordersClassOrActivityDto;
    }

    /**
     * 参数：
     * @param refundDto
     * @return 课程申请退款
     */
    @Transactional
    public void submitRefund(Refund refundDto) {
        if (BizEmpty(refundDto.getOrderNumber())){
            throw new BizException(ApiResultCode.PARAMETER_DEFICIENCY);
        }
        if (BizEmpty(refundDto.getRefundType())){
            throw new BizException(ApiResultCode.PARAMETER_DEFICIENCY);
        }
        if (BizEmpty(refundDto.getRefundCause())){
            throw new BizException(ApiResultCode.PARAMETER_DEFICIENCY);
        }
        if (BizEmpty(refundDto.getRefundRemark())){
            throw new BizException(ApiResultCode.PARAMETER_DEFICIENCY);
        }
        if (BizEmpty(commonUtils.getUserId(request))){
            throw new BizException(ApiResultCode.PARAMETER_DEFICIENCY);
        }

        OrdersClassOrActivity ordersClassOrActivity = new OrdersClassOrActivity();
        ordersClassOrActivity.setOrdersNumber(refundDto.getOrderNumber());
        //查询出退款课程订单
        OrdersClassOrActivity ordersClassOrActivity1 = ordersClassOrActivityMapper.selectOrderByOrdersNumber(ordersClassOrActivity);
        if (ordersClassOrActivity1 != null && ordersClassOrActivity1.getStatus() == 0){
            refundDto.setRefundStatus(-1);
            refundDto.setType(2);
            if (refundDto.getRefundImage() == null){
                refundDto.setRefundImage("[]");
            }
            refundMapper.saveRefund(refundDto);//加入退款表中

            OrdersClassOrActivity ordersClassOrActivity2 = new OrdersClassOrActivity();
            ordersClassOrActivity2.setUserId(Integer.parseInt(commonUtils.getUserId(request)));
            ordersClassOrActivity2.setOrdersNumber(refundDto.getOrderNumber());
            ordersClassOrActivity2.setFailStatus(1);
            ordersClassOrActivityMapper.updateFailStatus(ordersClassOrActivity2);//更改课程订单状态

        }else {
            throw new BizException(ApiResultCode.ORDERS_NULL);
        }
    }


    /**
     * 参数：订单编号
     * @param refund
     * @Return 课程订单退款详情
     */
    public Object RefundInfo(RefundDto refund) {

        if (BizEmpty(refund.getOrderNumber())){
            throw new BizException(ApiResultCode.PARAMETER_DEFICIENCY);
        }
        List<RefundDto> refundDto = refundMapper.selectRefundInfoByOrderNumber(refund);
        if (refundDto != null){
            return refundDto.get(0);
        }else {
            RefundDto refundDto1 = new RefundDto();
            return refundDto1;
        }

    }

    /**
     *  参数：订单编号、
     * @param refund 取消退款
     */
    @Transactional
    public void cancelRefund(Refund refund) {

        if (BizEmpty(commonUtils.getUserId(request))){
            throw new BizException(ApiResultCode.PARAMETER_DEFICIENCY);
        }
        if (BizEmpty(refund.getOrderNumber())){
            throw new BizException(ApiResultCode.PARAMETER_DEFICIENCY);
        }
        if (BizEmpty(refund.getRefundStatus())){
            throw new BizException(ApiResultCode.PARAMETER_DEFICIENCY);
        }
//        refund.setRefundStatus(3);
        refundMapper.updateRefundStatus(refund);
        OrdersClassOrActivity ordersClassOrActivity = new OrdersClassOrActivity();
        ordersClassOrActivity.setOrdersNumber(refund.getOrderNumber());
        ordersClassOrActivity.setUserId(Integer.parseInt(commonUtils.getUserId(request)));
        ordersClassOrActivity.setFailStatus(0);
        ordersClassOrActivityMapper.updateFailStatus(ordersClassOrActivity);

    }

    /**
     * 参数：订单编号、是否退款(1、同意，2：拒绝)、理由描述、描述图
     * @param refund 商家审核退款操作
     */
    @Transactional
    public void auditRefund(RefundDto refundDto) {

        if (BizEmpty(refundDto.getOrderNumber())){
            throw new BizException(ApiResultCode.PARAMETER_DEFICIENCY);
        }
        if (BizEmpty(refundDto.getShopRemark())){
            throw new BizException(ApiResultCode.PARAMETER_DEFICIENCY);
        }
        if (BizEmpty(commonUtils.getShopId(request))){
            throw new BizException(ApiResultCode.PARAMETER_DEFICIENCY);
        }
        if (BizEmpty(refundDto.getRefundStatus())){
            throw new BizException(ApiResultCode.PARAMETER_DEFICIENCY);
        }
        //查询退款订单
        OrdersClassOrActivity ordersClassOrActivity = new OrdersClassOrActivity();
        ordersClassOrActivity.setOrdersNumber(refundDto.getOrderNumber());
        OrdersClassOrActivity ordersClassOrActivity1 = ordersClassOrActivityMapper.selectOrderByOrdersNumber(ordersClassOrActivity);

        //查询退款课程
        ClassOrActivity classOrActivity = new ClassOrActivity();
        classOrActivity.setId(ordersClassOrActivity1.getClassOrActivityId());
        ClassOrActivity activityPrice = classOrActivityMapper.getActivityPrice(classOrActivity);

        /**同意退款*/
        if (refundDto.getRefundStatus() == 1){

            //增加用户退款积分
            HashMap<String, Object> map = new HashMap<>();
            map.put("integral",activityPrice.getPrice());
            map.put("userId",ordersClassOrActivity1.getUserId());
            userMapper.updateAccumulatePoints(map);

            //增加积分记录
            AccumulatePoints accumulatePoints = new AccumulatePoints();
            accumulatePoints.setOrderNumber(refundDto.getOrderNumber());
            accumulatePoints.setUserId(ordersClassOrActivity1.getUserId());
            accumulatePoints.setType(1);
            accumulatePoints.setAccumulatePoints(activityPrice.getPrice());
            accumulatePoints.setPayState(0);
            accumulatePoints.setDescribe("课程退款");
            accumulatePoints.setRecodeType(5);
            accumulatePointsMapper.saveAP(accumulatePoints);

            //商家帐户扣除积分
            ShopLogin shopLogin = new ShopLogin();
            shopLogin.setWallet(activityPrice.getPrice());
            shopLogin.setShopId(Integer.parseInt(commonUtils.getShopId(request)));
            shopLoginMapper.updWallet(shopLogin);

            //钱包日志记录  TODO
            WalletLog walletLog = new WalletLog();
            walletLog.setMoney(activityPrice.getPrice());
            walletLog.setType(2);
            walletLog.setShopId(Integer.parseInt(commonUtils.getShopId(request)));
            walletLog.setOrderNumber(refundDto.getOrderNumber());
            walletLog.setDescribe("课程退款");
            walletLog.setRecodeType(2);
            walletLogMapper.insertWalletLog(walletLog);

            //修改退款课程订单状态
            ordersClassOrActivity.setUserId(ordersClassOrActivity1.getUserId());
            ordersClassOrActivity.setFailStatus(3);
            ordersClassOrActivityMapper.updateFailStatus(ordersClassOrActivity);

            //更改退款表订单内容
            refundMapper.updateRefund(refundDto);

        }else {/** 拒绝退款*/
            //修改退款课程订单状态
            ordersClassOrActivity.setFailStatus(2);
            ordersClassOrActivity.setUserId(ordersClassOrActivity1.getUserId());
            ordersClassOrActivityMapper.updateFailStatus(ordersClassOrActivity);
            //更改退款表订单内容
            refundMapper.updateRefund(refundDto);
        }
    }

    @Transactional
    public void signUpOrOut(ClassSign classSign) throws ParseException {
        int userId = Integer.parseInt(commonUtils.getUserId(request));
        User user = new User();
        AccumulatePoints accumulatePoints = new AccumulatePoints();
        user.setUserId(userId);
        String locations = classSign.getLocations();
        List<Double> locationArr = JSONArray.parseArray(locations, Double.class);
        ClassOrActivityDto classOrActivityDto = new ClassOrActivityDto();
        classOrActivityDto.setId(classSign.getClassOrActivityId());
        ClassOrActivityDto info = classOrActivityMapper.findInfo(classOrActivityDto);
        if (!checkLocations(locationArr.get(0), locationArr.get(1),
                info.getLongitude().doubleValue(), info.getLatitude().doubleValue(),
                info.getScope())) {
            throw new BizException(ApiResultCode.LOCATION_NOT_SCOPE);

        }
        classSign.setUserId(userId);
        //获取课程id
        OrdersClassOrActivity ordersClassOrActivity = new OrdersClassOrActivity();
        ordersClassOrActivity.setUserId(userId);
        ordersClassOrActivity.setClassOrActivityId(classSign.getClassOrActivityId());
        OrdersClassOrActivity activity = ordersClassOrActivityMapper.findOrdersByUserIdAndClassOrActivityId(ordersClassOrActivity);
        if (activity == null) {
            throw new BizException(ApiResultCode.CLASS_NOT_EXIST);
        }
        //获取当前签到日期
        int weekOfDate = getWeekOfDate(new Date());
        ClassSchedule classSchedule = new ClassSchedule();
        classSchedule.setWeek(weekOfDate);
        classSchedule.setClassOrActivityId(classSign.getClassOrActivityId());
        ClassSchedule classSchedule1 = ordersClassOrActivityMapper.getClassSchedule(classSchedule);
        if (classSchedule1 == null) {
            throw new BizException(ApiResultCode.CLASS_NOT_TODAY);
        }
        int nowTime = DateToNumber(getNowTime());
        String attendTime = classSchedule1.getAttendTime();
        List<DateDto> jsonArray = JSONArray.parseArray(attendTime, DateDto.class);
        //判断用户签到/签退
        SignParameter signParameter = judgeSign(jsonArray, userId, classSign.getClassOrActivityId());
        DateScopeDto dateScopeDto = isTimeScope(nowTime, jsonArray,signParameter.isSign()?1:2); //获取签到区间
        //获取记录表签到区间记录
        ClassSign classSign1 = new ClassSign();
        classSign1.setUserId(userId);
        classSign1.setSectionStartTime(numberToDate(dateScopeDto.getStart_time()));
        classSign1.setSectionEndTime(numberToDate(dateScopeDto.getEnd_time()));
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
        String format = simpleDateFormat.format(new Date());
        Date parse = simpleDateFormat.parse(format);
        classSign1.setSignDate(parse);
        classSign1.setClassOrActivityId(classSign.getClassOrActivityId());
        classSign1.setClassOrActivityId(classSign.getClassOrActivityId());
        List<ClassSign> signRecodeBySection = ordersClassOrActivityMapper.getSignRecodeBySection(classSign1);
        if (signParameter.isSign()) {
            //校验是否有课程进行
            judgeCourseIng(userId, weekOfDate);

            //签到 校验签到时间范围 打卡范围内返回打卡区间时间
            if (!dateScopeDto.isFlag()) {
                throw new BizException(ApiResultCode.SIGN_NOT_TIME);
            }

            //用户签到积分
            if (signRecodeBySection.size()<1){
                if (nowTime<=dateScopeDto.getStart_time()){
                    accumulatePoints.setDescribe("签到积分"); //记录描述
                    signIntegral(user,accumulatePoints); //签到积分增加
                }

            }
            classSign.setSignLocations(classSign.getLocations());
            classSign.setSectionStartTime(numberToDate(dateScopeDto.getStart_time()));
            classSign.setSectionEndTime(numberToDate(dateScopeDto.getEnd_time()));
            ordersClassOrActivityMapper.addSignRecode(classSign);
        } else {

            //判断用户
            if (signRecodeBySection.size()<2){
                //用户签退 更新用户签到积分
                if (nowTime>=dateScopeDto.getEnd_time()){
                    accumulatePoints.setDescribe("签退积分"); //记录描述
                    signIntegral(user,accumulatePoints); //签到积分增加
                }

                //当前课程区间首次签退
//                classSign.setSignLocations(classSign.getLocations());
//                ordersClassOrActivityMapper.addSignRecode(classSign);
                //获取上次签到信息
                for (ClassSign sign : signRecodeBySection) {
                    if (sign.getEndTime()==null){
                        //获取签到时间
                        int start_time = dateScopeDto.getStart_time();
                        int end_time = dateScopeDto.getEnd_time();
                        int sign_start_time = DateToNumber(getTimeByDate(sign.getStartTime()));
                        if (sign_start_time<=start_time && end_time<=DateToNumber(getNowTime())){
                            //积分奖励
                            accumulatePoints.setDescribe("打卡奖励"); //记录描述
                            signIntegral(user,accumulatePoints); //签到积分增加
                        }
                    }
                }

            }
            classSign.setId(signParameter.getId());
            if (signParameter.getAhead() < 0) {
                //提前签到
                classSign.setLongTime(Math.max(nowTime - signParameter.getClassStartTime(), 0));
            } else {
                classSign.setLongTime(nowTime - signParameter.getSignStartTime());
            }
            classSign.setSignOutLocations(classSign.getLocations());
            ordersClassOrActivityMapper.updateSignById(classSign);
//            accumulatePointsMapper.saveAP(accumulatePoints);



        }


    }

    /**
     * 积分记录添加和用户签到积分增加
     * @param user
     * @param accumulatePoints
     */
    public void signIntegral(User user,AccumulatePoints accumulatePoints){
        user.setSignIntegral(new BigDecimal(1)); //用户余额更新
        accumulatePoints.setUserId(user.getUserId());
        accumulatePoints.setOrderNumber(getOrderNo());
        accumulatePoints.setType(1);
        accumulatePoints.setAccumulatePoints(new BigDecimal(1));
        accumulatePoints.setPayState(0);
        accumulatePoints.setRecodeType(1);
        accumulatePointsMapper.saveAP(accumulatePoints);
        userMapper.updSignIntegral(user);


    }

    public List<String> scheduleInfoByCalendar(DateVo dateVo) throws ParseException {
        String userId = commonUtils.getUserId(request);
        OrdersClassOrActivity ordersClassOrActivity = new OrdersClassOrActivity();
        ordersClassOrActivity.setUserId(Integer.parseInt(userId));
        List<OrdersClassOrActivity> ordersByUserId = ordersClassOrActivityMapper.findOrdersByUserId(ordersClassOrActivity);//查出报名那些课程
        ArrayList<Integer> list = new ArrayList<>();//获得报名课程id
        ArrayList<String> list2 = new ArrayList<>();
        ArrayList<String> list3 = new ArrayList<>();
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");

        for (OrdersClassOrActivity classOrActivity : ordersByUserId) {
            Integer classOrActivityId = classOrActivity.getClassOrActivityId();
            list.add(classOrActivityId);
        }
        ClassScheduleDto classScheduleDto = new ClassScheduleDto();
        classScheduleDto.setId(list);
        if (list.size()==0){
            return list3;
        }

        List<ClassSchedule> classSchedules = ordersClassOrActivityMapper.findClassScheduleWeek(classScheduleDto);//拿报名课程id查询出课程在星期几
        List<ClassOrActivity> activityTime = ordersClassOrActivityMapper.findActivityTime(classScheduleDto);//报名的课程
        for (ClassOrActivity classOrActivity : activityTime) {//循环看课程是星期几在哪天
            Date startTime = classOrActivity.getStartTime();//活动开始时间
            Date endTime = classOrActivity.getEndTime();//活动结束时间
            Date parse1 = simpleDateFormat.parse(dateVo.getDate());//传来要查看的日期

            String[] split = dateVo.getDate().split("-");//传来要查看的日期
            Integer year = Integer.valueOf(split[0]);//年
            Integer month = Integer.valueOf(split[1]);//月

            String formats = simpleDateFormat.format(startTime);//活动开始时间
            String[] split1 = formats.split("-");
            Integer year1 = Integer.valueOf(split1[0]);//年
            Integer month1 = Integer.valueOf(split1[1]);//月
            Integer day1 = Integer.valueOf(split1[2]);//日

            String format = simpleDateFormat.format(endTime);//活动结束时间
            String[] split2 = format.split("-");
            Integer year2 = Integer.valueOf(split2[0]);//年
            Integer month2 = Integer.valueOf(split2[1]);//月
            Integer day2 = Integer.valueOf(split2[2]);//日

            //如果要查看的年份不等于活动年份，或者要查看的月份小于活动开始月份，或者大于活动结束月份
            //如果a比b小,那么返回-1,相等就是0,否则就是1
            if (compare(year,year1) != 0 & compare(year,year2) != 0){
                return list3;
            }else if (compare(year,year1) == 0 && compare(month,month1) ==-1){
                return list3;
            }else if (compare(year,year2) == 0 && compare(month,month2) ==1){
                return list3;
            }

            //要查看的这个月的天数
            int s = 0;
            boolean flag = false;
            Integer monthDays = getMonthDays(parse1);
            if (compare(year,year1) == 0 && compare(month,month1) ==0){
                 s = monthDays - (day1-1);
                flag = false;
            }else if (compare(year,year2) == 0 && compare(month,month2) ==0){
                s = day2;
                flag = true;
            }else {
                 s = monthDays;
                 flag = false;
            }

            //转化 要查看的 这个月的天数是哪几号
            String day = "";
            ArrayList<String> list1 = new ArrayList<>();

            if (flag == false){
                for (Integer i = 0; i < s; i++) {
                    day = year + "-" + month + "-" + (monthDays-i);
                    list1.add(day);
                }
            }else {
                for (Integer i = 1; i <= s; i++) {
                    day = year + "-" + month + "-" + i;
                    list1.add(day);
                }
            }

            //循环出这个月的每号是星期几有没有课程 返出去
            for (int j = 0; j < list1.size(); j++) {
                String s1 = list1.get(j);
                Date parse = simpleDateFormat.parse(s1);
                int weekOfDate = DateUtil.getWeekOfDate(parse);//获取当前日期星期几
                for (ClassSchedule classSchedule : classSchedules) {
                    if (weekOfDate == classSchedule.getWeek()) {//循环报名课程星期
                        list2.add(s1);
                    }
                }
            }
            break;
        }
        return list2;
    }

    public static int compare(int x, int y)
    {
        //如果a比b小,那么返回-1,相等就是0,否则就是1
        return (x < y) ? -1 : ((x == y) ? 0 : 1);
    }

    public List<ScheduleInfoDto> getScheduleByDate(DateVo dateVo) throws ParseException {
        int userId = Integer.parseInt(commonUtils.getUserId(request));
        ArrayList<ScheduleInfoDto> arr = new ArrayList<>();
        OrdersClassOrActivity ordersClassOrActivity = new OrdersClassOrActivity();
        ordersClassOrActivity.setUserId(userId);
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
        Date parse = simpleDateFormat.parse(dateVo.getDate()); //前端传的日期
        int dayOfWeek = getWeekOfDate(parse);
        //获取用户报名课程id
        HashSet<Integer> classIds = getClassIdByUserId(ordersClassOrActivity);

        //
        ClassScheduleDto classScheduleDto = new ClassScheduleDto();
        classScheduleDto.setId(new ArrayList<>(classIds));
        if (classIds.size()==0){
            return arr;
        }
        //课程时间
        List<ClassOrActivity> activityTimes = ordersClassOrActivityMapper.findActivityTime(classScheduleDto);
        for (ClassOrActivity activityTime : activityTimes) {
            Date startTime = activityTime.getStartTime();
            Date endTime = activityTime.getEndTime();
            if (parse.getTime()<startTime.getTime() || parse.getTime()>endTime.getTime()){
                classIds.remove(activityTime.getId());
            }

        }
        if (classIds.size()==0){
            return arr;
        }

        HashMap<String, Object> parameterMap = new HashMap<>();
        parameterMap.put("classIds", classIds);
        parameterMap.put("week", dayOfWeek);
        List<ClassSchedule> scheduleByDate = ordersClassOrActivityMapper.getScheduleByDate(parameterMap);
        for (ClassSchedule classSchedule : scheduleByDate) { //课程
            ClassOrActivityDto classOrActivityDto = new ClassOrActivityDto();
            classOrActivityDto.setId(classSchedule.getClassOrActivityId());
            String attendTime = classSchedule.getAttendTime(); //上课时间
            List<DateDto> dateDtos = JSONArray.parseArray(attendTime, DateDto.class);
            ClassOrActivityDto info = classOrActivityMapper.findInfo(classOrActivityDto);
//            ClassSchedule classScheduleRes = ordersClassOrActivityMapper.getClassSchedule(classSchedule);
            for (DateDto dateDto : dateDtos) { //每个课程时间
                ScheduleInfoDto scheduleInfoDto = new ScheduleInfoDto();
                scheduleInfoDto.setId(info.getId());
                scheduleInfoDto.setTitle(info.getClassName());
                scheduleInfoDto.setStartTime(dateDto.getStart_time());
                scheduleInfoDto.setStartTimeSort(DateToNumber(dateDto.getStart_time()));
                scheduleInfoDto.setEndTime(dateDto.getEnd_time());
                String isSign = "-1";
                String isLine = "0" ; // 0 不显示激活线条 1 显示激活线条
                //判断是否是当天
                boolean nowDate = isNowDate(parse);
                if (nowDate) {
                    isSign = isStart(dateDto, parse) + "";
                    //显示进度条
                    if (DateToNumber(dateDto.getStart_time()) <= DateToNumber(getNowTime()) + excursionTime) {
                        isLine = "1";
                    }
                }
                scheduleInfoDto.setIsSign(isSign);
                scheduleInfoDto.setIsLine(isLine);
                arr.add(scheduleInfoDto);
            }
        }
        return sortList(arr);
    }

    /**
     *  参数：用户id
     * @param user 老师权限 查看我的班级
     * @return
     */
    public Object myClass(UserDto user) {
        if (BizEmpty(commonUtils.getUserId(request))){
            throw new BizException(ApiResultCode.PARAMETER_DEFICIENCY);
        }
        user.setUserId(Integer.parseInt(commonUtils.getUserId(request)));
        //查询用户表老师信息
        UserDto userInfo = userMapper.getUserInfoById(user);

        Teacher teacher = new Teacher();
        teacher.setPhone(userInfo.getPhone());
        teacher.setStates(0);
        //获取教师id
        List<Teacher> teacherList = teacherService.getClassByPhone(teacher);
        ArrayList<Object> list = new ArrayList<>();
        if (teacherList.size()>0){

            //根据老师获取所带的班级
            List<TeacherShop> bindClassByTeacher = teacherService.getBindClassByTeacher(teacherList);
            if (bindClassByTeacher.size()>0){
                for (TeacherShop teacherShop : bindClassByTeacher) {

                    ClassOrActivityDto classOrActivityDto = classOrActivityMapper.selectActivityInfo(teacherShop.getScheduleId());
                    list.add(classOrActivityDto);
                }
            }
        }

        return list;
    }



    /**
     *  参数：课堂id 学校id 老师权限
     * @param ordersClassOrActivity 移动端课程报名信息列表
     * @return
     */
    public PageInfo<OrdersClassOrActivityDto> classStudents(OrdersClassOrActivity ordersClassOrActivity) {

        if (BizEmpty(ordersClassOrActivity.getClassOrActivityId())){
            throw new BizException(ApiResultCode.PARAMETER_DEFICIENCY);
        }
        if (BizEmpty(ordersClassOrActivity.getShopId())){
            throw new BizException(ApiResultCode.PARAMETER_DEFICIENCY);
        }

        List<OrdersClassOrActivityDto> ordersClassOrActivityDtos = ordersClassOrActivityMapper.classStudents(ordersClassOrActivity);

        return new PageInfo<>(ordersClassOrActivityDtos);
    }



    /**
     *
     * @param nowTime
     * @param jsonArray
     * @return 返回是否可以签到和签退时间区间
     */
    public DateScopeDto isTimeScope(int nowTime, List<DateDto> jsonArray,Integer type) {
        DateScopeDto dateScopeDto = new DateScopeDto();
        //签到 校验签到时间范围
        dateScopeDto.setFlag(false); //未通过校验
        dateScopeDto.setType(type);
        for (DateDto dateDto : jsonArray) {
            int start_time = DateToNumber(dateDto.getStart_time());
            int end_time = DateToNumber(dateDto.getEnd_time());
            if (type==1){ //签到
                if (nowTime >= (start_time - excursionTime) && nowTime < end_time) {
                    dateScopeDto.setFlag(true);
                    dateScopeDto.setStart_time(start_time);
                    dateScopeDto.setEnd_time(end_time);
                    return dateScopeDto;
                }
            }

            if (type==2){ //签退
                if (nowTime >= start_time  && nowTime <= end_time+excursionTime) {
                    dateScopeDto.setFlag(true);
                    dateScopeDto.setStart_time(start_time);
                    dateScopeDto.setEnd_time(end_time);
                    return dateScopeDto;
                }else {
                    throw new BizException(ApiResultCode.SIGN_TIME_NOT);
                }
            }

        }
        return dateScopeDto;
    }

    public int getSignLongTime(ClassSign classSign) {//参数：user_id
        classSign.setUserId(Integer.parseInt(commonUtils.getUserId(request)));
        if (BizEmpty(classSign.getUserId())) {
            throw new BizException(ApiResultCode.NOT_TOKEN);
        }
        ClassSign classSignRes = new ClassSign();
        ClassSign longTime = ordersClassOrActivityMapper.findLongTime(classSign);
        if (longTime == null) {
            classSignRes.setLongTime(0);
        }else {
            classSignRes.setLongTime(longTime.getLongTime());
        }
        return classSignRes.getLongTime();
    }

    public List<ScheduleInfoDto> sortList(List<ScheduleInfoDto> List) {
        List.sort(new Comparator<ScheduleInfoDto>() {
            @Override
            public int compare(ScheduleInfoDto o1, ScheduleInfoDto o2) {
                if ((o1.getStartTimeSort() > o2.getStartTimeSort())) {
                    return 1;
                }
                if (o1.getStartTimeSort().equals(o2.getStartTimeSort())) {
                    return 0;
                }
                return -1;
            }
        });
        return List;
    }

    /**
     * 课程是否在签到时间范围
     *
     * @param dateDto 时间区间
     * @param date    当前时间
     * @return -1 不在时间范围 0 在时间范围 1 签到 2 签退
     */
    public int isStart(DateDto dateDto, Date date) throws ParseException {
        String nowTime1 = getNowTime();
        //判断是否在时间范围
        int startTime = DateToNumber(dateDto.getStart_time());
        int endTime = DateToNumber(dateDto.getEnd_time());
        int nowTime = DateToNumber(nowTime1);
        if (nowTime >= startTime - excursionTime && nowTime <= endTime + excursionTime) {

            return 0;
        }
        return -1;
    }

    /**
     * @param date 当前日期
     * @return 是当前日期
     */
    public boolean isNowDate(Date date) {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
        String vo = simpleDateFormat.format(date);
        String sys = simpleDateFormat.format(new Date());
        return vo.equals(sys);

    }

    /**
     * @param ordersClassOrActivity 用户id
     * @return
     */
    public HashSet<Integer> getClassIdByUserId(OrdersClassOrActivity ordersClassOrActivity) {
        List<OrdersClassOrActivity> ordersByUserId = ordersClassOrActivityMapper.findOrdersByUserId(ordersClassOrActivity);
        HashSet<Integer> setRes = new HashSet<>();
        for (OrdersClassOrActivity classOrActivity : ordersByUserId) {
            setRes.add(classOrActivity.getClassOrActivityId());
        }
        return setRes;


    }

    public boolean checkLocations(double lng1, double lat1, double lng2, double lat2, Integer scope) {
        double distance = getDistance(lat1, lng1, lat2, lng2);
        return distance <= scope;

    }

    public boolean judgeCourseIng(Integer userId, int week) throws ParseException {
        ClassSign classSign = new ClassSign();
        classSign.setUserId(userId);
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
        String format = simpleDateFormat.format(new Date());
        Date parse = simpleDateFormat.parse(format);
        classSign.setSignDate(parse);
        classSign.setSignOutLocations("99"); //代表未进行签退
        List<ClassSign> signRecode = ordersClassOrActivityMapper.getSignRecode(classSign);
        for (ClassSign sign : signRecode) {
            ClassSchedule classSchedule = new ClassSchedule();
            classSchedule.setWeek(week);
            classSchedule.setClassOrActivityId(sign.getClassOrActivityId());
            //课程信息
            ClassSchedule classSchedule1 = ordersClassOrActivityMapper.getClassSchedule(classSchedule);
            List<DateDto> jsonArray = JSONArray.parseArray(classSchedule1.getAttendTime(), DateDto.class);
            DateScopeDto dateScopeDto = isTimeScope(DateToNumber(getNowTime()), jsonArray,1);
            if (dateScopeDto.isFlag()){
                //在时间范围内
                throw new BizException(ApiResultCode.NOT_ALLOW_SIGN);
            }

        }
        return true;
    }

    public SignParameter judgeSign(List<DateDto> jsonArray, Integer userId, Integer activityId) throws ParseException {
        int nowTime = DateToNumber(getNowTime());
        SignParameter signParameter = new SignParameter();
        ClassSign classSign = new ClassSign();
        classSign.setUserId(userId);
        classSign.setClassOrActivityId(activityId);
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
        String format = simpleDateFormat.format(new Date());
        Date parse = simpleDateFormat.parse(format);
        classSign.setSignDate(parse);
        List<ClassSign> signRecode = ordersClassOrActivityMapper.getSignRecode(classSign);
        signParameter.setSign(true);
        for (ClassSign sign : signRecode) {
            if (sign.getEndTime() == null) {
                //判断签到签退
                int signStartTimeNumber = DateToNumber(getTimeByDate(sign.getStartTime())); //签到开始时间
                DateDto dataDto = getEndTimeByStartTime(signStartTimeNumber, jsonArray);
                if (dataDto != null){
                    int endTimeNumber = DateToNumber(dataDto.getEnd_time());
                    int startTimeNumber = DateToNumber(dataDto.getStart_time()); //课程开始时间
                    if (endTimeNumber > 0) {
                        //签退
                        if (nowTime <= endTimeNumber + excursionTime) { //结束时间
                            int signStartTime = DateToNumber(getTimeByDate(sign.getStartTime()));
                            signParameter.setId(sign.getId());
                            signParameter.setSignStartTime(signStartTime);
                            signParameter.setAhead(signStartTimeNumber - startTimeNumber);
                            signParameter.setClassStartTime(DateToNumber(dataDto.getStart_time()));
                            signParameter.setSign(false);
                        }
                    }
                }


            }
        }
        return signParameter;

    }


    /**
     * 根据开始时间获取结束时间
     *
     * @param signStartTimeNumber
     * @param jsonArray
     * @return
     */
    public DateDto getEndTimeByStartTime(int signStartTimeNumber, List<DateDto> jsonArray) {
        for (DateDto dateDto : jsonArray) {
            int start_time = DateToNumber(dateDto.getStart_time());
            int end_time = DateToNumber(dateDto.getEnd_time());
            if (signStartTimeNumber >= start_time - excursionTime && signStartTimeNumber < end_time) {
                return dateDto;
            }
        }
        return null;

    }

    public String getNowTime() {
        Date date = new Date();
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("HH:mm");
        return simpleDateFormat.format(date);
    }

    public String getTimeByDate(Date date) {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("HH:mm");
        return simpleDateFormat.format(date);
    }

    public int DateToNumber(String date) {
        String[] replace = date.split(":");
        return (Integer.parseInt(replace[0])) * 60 + Integer.parseInt(replace[1]);
    }

    public String numberToDate(Integer numberDate) {
        int hour = numberDate / 60;
        int minute = numberDate % 60;
        return hour + ":" + minute;

    }


    //获取月份天数
    private Integer getMonthDays(Date date) {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
        String format = simpleDateFormat.format(date);
        String[] split = format.split("-");
        String year = split[0];
        String month = split[1];

        if ("02".equals(month)) {
            //判断润平年
            int i = Integer.parseInt(year) % 4;
            if (i == 0) {
                //闰年
                return 29;

            } else {
                //平年
                return 28;
            }
        } else {
            if ("01".equals(month) || "03".equals(month) || "05".equals(month)
                    || "07".equals(month) || "08".equals(month) || "10".equals(month) || "12".equals(month)) {
                return 31;
            } else {
                return 30;
            }
        }
    }
}
